﻿using Aribaccio;
using BDPAutodetect.Device;
using BDPAutodetect.Mgrcore;
using BDPAutodetect.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using log4net;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace BDPAutodetect.Client
{
    /// <summary>
    /// 检测指标视图模型类
    /// </summary>
    public partial class DetectTargetViewModel : BaseViewModel<UserControl>
    {
        /// <summary>
        /// 用户管理实例
        /// </summary>
        protected UserManager UserMgr { get; set; }
        /// <summary>
        /// 指标设备协议管理实例
        /// </summary>
        protected TargetSlaveManager TargetSlaveMgr { get; set; }

        /// <summary>
        /// 查询当前工位
        /// </summary>
        [ObservableProperty]
        protected MStation? stationItem;
        /// <summary>
        /// 查询工位集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MStation> stationItems;
        /// <summary>
        /// 查询当前从机设备
        /// </summary>
        [ObservableProperty]
        protected MSlave? slaveItem;
        /// <summary>
        /// 查询从机设备集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MSlave> slaveItems;
        /// <summary>
        /// 查询当前设备类型
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(IsVisibilitySlave))]
        protected DeviceTypeData deviceTypeItem;
        /// <summary>
        /// 查询设备类型集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<DeviceTypeData> deviceTypeItems;
        /// <summary>
        /// 指标设备协议数据集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MTargetSlave> targetSlaveItems;

        /// <summary>
        /// 是否可见新增
        /// </summary>
        [ObservableProperty]
        protected bool isEnabledInsert = false;
        /// <summary>
        /// 是否可见删除
        /// </summary>
        [ObservableProperty]
        protected bool isEnabledDelete = false;
        /// <summary>
        /// 是否可见复制
        /// </summary>
        [ObservableProperty]
        protected bool isEnabledClone = false;
        /// <summary>
        /// 是否可以显示按钮
        /// </summary>
        [ObservableProperty]
        protected Visibility isVisibility = Visibility.Hidden;
        /// <summary>
        /// 是否可以显示从机协议数据【Modbus】
        /// </summary>
        public bool IsVisibilitySlave => this.DeviceTypeItem.DeviceType != DeviceType.None && this.DeviceTypeItem.DeviceType != DeviceType.Customer;

        /// <summary>
        /// 构造函数
        /// </summary>
        public DetectTargetViewModel(UserManager argUserManager, TargetSlaveManager argTargetSlaveManager)
        {
            this.UserMgr = argUserManager;
            this.TargetSlaveMgr = argTargetSlaveManager;
            //查询选项
            this.StationItems = new ObservableCollection<MStation>();
            this.SlaveItems = new ObservableCollection<MSlave>();
            this.DeviceTypeItems = new ObservableCollection<DeviceTypeData>();
            this.TargetSlaveItems = new ObservableCollection<MTargetSlave>();
            foreach (var item in DeviceTypeTable.Items)
            {
                if (item.DeviceType == DeviceType.None) continue;
                this.DeviceTypeItems.Add(item);
            }
            this.DeviceTypeItem = this.DeviceTypeItems.First();
            //更新是否显示状态
            if (this.UserMgr.LoginUser?.Supered > 0)
            {
                this.IsVisibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// 初始化加载权限编辑
        /// </summary>
        /// <returns></returns>
        protected async Task InitLoadPermission()
        {
            if (this.PowerPermission == null) return;
            var resultTaskPowers = this.UserMgr.GetUserPowers(this.PowerPermission.Power.ID);
            await resultTaskPowers.ConfigureAwait(false);
            if (resultTaskPowers != null && resultTaskPowers.Result != null && resultTaskPowers.Result.Count > 0)
            {
                this.IsVisibilityPermission = Visibility.Visible;
            }
        }

        /// <summary>
        /// 初始化加载查询选项数据集
        /// </summary>
        /// <returns></returns>
        protected async Task InitLoadItems()
        {
            await Task.Factory.StartNew(() =>
            {
                //初始化工位数据
                var stations = this.TargetSlaveMgr.GetStations();
                foreach (var stationItem in stations)
                {
                    this.StationItems.Add(stationItem);
                }
                this.StationItem = this.StationItems.FirstOrDefault();
                //初始化从机设备数据
                var slaves = this.TargetSlaveMgr.GetSlaves();
                foreach (var item in slaves.OrderBy(v => v.ID))
                {
                    if (this.UserMgr.LoginUser?.Supered <= 0 && item.ID <= 0) continue;
                    this.SlaveItems.Add(item);
                }
                if (this.UserMgr.LoginUser?.Supered <= 0)
                    this.SlaveItem = this.SlaveItems.First();
                else
                    this.SlaveItem = this.SlaveItems.First(v => v.ID > 0);

            }, new CancellationTokenSource().Token, TaskCreationOptions.None, base.syncContextTask);
        }

        /// <summary>
        /// 页面初始化加载事件
        /// </summary>
        [RelayCommand]
        public async Task ExecuteLoaded()
        {
            if (this.IsLoaded) return;
            //获取编辑权限
            var resultTask = this.InitLoadPermission();
            await resultTask.ConfigureAwait(false);

            //获取查询选项数据集
            resultTask = this.InitLoadItems();
            await resultTask.ConfigureAwait(false);

            //标记初始化加载完成
            this.IsLoaded = true;
            //初始化查询数据
            resultTask = this.ExecuteQuery();
            await resultTask.ConfigureAwait(false);
        }

        /// <summary>
        /// 删除命令事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteDelete()
        {
            this.ResetStartus(false);
            try
            {
                var result = this.TargetSlaveMgr.DeleteTargetSlave(new QueryTargetSlaveDto()
                {
                    SlaveID = this.SlaveItem?.ID ?? 0,
                    StationID = this.StationItem?.ID ?? 0,
                    Category = this.DeviceTypeItem.DeviceType.ToInt(),
                    DeviceType = this.DeviceTypeItem.DeviceType,
                    StationType = this.StationItem?.StationType ?? DeviceStationType.None
                });
                await result.ConfigureAwait(false);
                if (result != null && result.Result)
                {
                    await this.ResetTargetSlaves();
                }
                else
                {
                    MessageBox.Show("删除失败！", "警告", MessageBoxButton.OK);
                }
            }
            finally
            {
                this.ResetStartus(true);
            }
        }

        /// <summary>
        /// 新增命令事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteInsert()
        {
            this.ResetStartus(false);
            try
            {
                QueryTargetSlaveDto QueryDto = new QueryTargetSlaveDto()
                {
                    SlaveID = this.SlaveItem?.ID ?? 0,
                    StationID = this.StationItem?.ID ?? 0,
                    Category = this.DeviceTypeItem.DeviceType.ToInt(),
                    DeviceType = this.DeviceTypeItem.DeviceType,
                    StationType = this.StationItem?.StationType ?? DeviceStationType.None
                };
                var result = this.TargetSlaveMgr.InsertTargetSlave(QueryDto);
                await result.ConfigureAwait(false);
                if (result != null && result.Result)
                {
                    await this.QueryData(QueryDto);
                }
                else
                {
                    MessageBox.Show("新增失败！", "警告", MessageBoxButton.OK);
                }
            }
            finally
            {
                this.ResetStartus(true);
            }
        }

        /// <summary>
        /// 复制命令事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteClone()
        {
            this.ResetStartus(false);
            try
            {
                QueryTargetSlaveDto sourceQueryDto = new QueryTargetSlaveDto()
                {
                    SlaveID = this.SlaveItem?.ID ?? 0,
                    StationID = this.StationItem?.ID ?? 0,
                    Category = this.DeviceTypeItem.DeviceType.ToInt(),
                    DeviceType = this.DeviceTypeItem.DeviceType,
                    StationType = this.StationItem?.StationType ?? DeviceStationType.None
                };
                //弹出层
                TargetSlaveDialog dialog = new TargetSlaveDialog("复制", sourceQueryDto, this.StationItems, this.SlaveItems);
                bool? bResult = dialog.ShowDialog();
                if (!bResult.HasValue || !bResult.Value) return;
                if (dialog.DialogResultData == null) return;

                var resultData = dialog.DialogResultData;
                resultData.Category = sourceQueryDto.Category;
                resultData.DeviceType = sourceQueryDto.DeviceType;
                var result = this.TargetSlaveMgr.CloneTargetSlave(sourceQueryDto, resultData);
                await result.ConfigureAwait(false);
                if (result != null && result.Result)
                {
                    this.SlaveItem = this.SlaveItems.First(v => v.ID == resultData.SlaveID);
                    this.StationItem = this.StationItems.First(v => v.StationType == resultData.StationType);
                    this.DeviceTypeItem = this.DeviceTypeItems.First(v => v.DeviceType == resultData.DeviceType);
                    await this.QueryData(resultData);
                }
                else
                {
                    MessageBox.Show("复制失败！", "警告", MessageBoxButton.OK);
                }
            }
            finally
            {
                this.ResetStartus(true);
            }
        }

        /// <summary>
        /// 编辑命令事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteEditor(MTargetSlave argTargetSlave)
        {
            this.ResetStartus(false);
            try
            {
                //编辑弹出层
                TargetSlaveEditorDialog editorDialog = new TargetSlaveEditorDialog(argTargetSlave, this.StationItems, this.SlaveItems, new ObservableCollection<MTarget>(this.TargetSlaveMgr.Targets));
                bool? bResult = editorDialog.ShowDialog();
                if (!bResult.HasValue || !bResult.Value) return;
                if (editorDialog.DialogResultData == null) return;

                var result = this.TargetSlaveMgr.UpdateTargetSlave(editorDialog.DialogResultData);
                await result.ConfigureAwait(false);
            }
            finally
            {
                this.ResetStartus(true);
            }
        }

        /// <summary>
        /// 查询命令事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteQuery()
        {
            if (!this.IsExecutedIdle) return;
            //设置非空闲忙碌中
            this.ResetStartus(false);
            var resultTask = this.QueryData(new QueryTargetSlaveDto()
            {
                SlaveID = this.SlaveItem?.ID ?? 0,
                StationID = this.StationItem?.ID ?? 0,
                Category = this.DeviceTypeItem.DeviceType.ToInt(),
                DeviceType = this.DeviceTypeItem.DeviceType,
                StationType = this.StationItem?.StationType ?? DeviceStationType.None
            });
            await resultTask.ConfigureAwait(false);
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        public async Task QueryData(QueryTargetSlaveDto argQueryData)
        {
            await Task.Factory.StartNew(() =>
            {
                try
                {
                    this.TargetSlaveItems.Clear();
                    var resultDatas = this.TargetSlaveMgr.GetTargetSlaves(argQueryData);
                    if (resultDatas != null)
                    {
                        var orderDatas = resultDatas.OrderBy(v => v.Target.ID);
                        foreach (var item in orderDatas)
                        {
                            this.TargetSlaveItems.Add(item);
                        }
                    }
                }
                finally
                {
                    this.ResetStartus(true);
                }
            }, new CancellationTokenSource().Token, TaskCreationOptions.None, base.syncContextTask);
        }

        /// <summary>
        /// 重置查询结果
        /// </summary>
        /// <returns></returns>
        protected async Task ResetTargetSlaves()
        {
            await Task.Factory.StartNew(() =>
            {
                this.TargetSlaveItems.Clear();
            }, new CancellationTokenSource().Token, TaskCreationOptions.None, base.syncContextTask);
        }

        /// <summary>
        /// 重置状态
        /// </summary>
        protected void ResetStartus(bool argStartus)
        {
            this.IsExecutedIdle = argStartus;
            if (argStartus)
            {
                this.IsEnabledInsert = this.TargetSlaveItems.Count <= 0;
                this.IsEnabledClone = this.TargetSlaveItems.Count > 0;
                this.IsEnabledDelete = this.TargetSlaveItems.Count > 0 && this.SlaveItem.ID != 1 && !this.SlaveItem.Name.Equals("Default", StringComparison.OrdinalIgnoreCase);
            }
            else
            {
                this.IsEnabledInsert = false;
                this.IsEnabledDelete = false;
                this.IsEnabledClone = false;
            }
        }
    }
}
